{
Traviesadora beta 0.2.0.13.33 (30.11.2008)
LastMod: 12.12.2008 by Prof1983

Copyright 2008, travieorama@googlemail.com

This file is part of the taviesadora project

taviesadora is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

taviesadora is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
}
unit VersionChecker;

interface

uses
  Forms, IniFiles, Classes, ExtCtrls, SysUtils, IdHttp, XmlParser, XmlTag, Service, {VibDriver,}
  DialogWin, ShellApi, Windows;

type
  TVersion=class
    constructor create(ver:string;rev,state:string);
    constructor CreateByTag(xmltag:TXMLTag);
    constructor CreateByVersion(v:TVersion);
    public
    major,minor,release,build,rev :integer;
    state:string;
  end;
  TVersionRecord=record
    version:TVersion;
    link:string;
    priority:string;
    desc:string;
    date:TDateTime;
  end;
  TversionChecker = class
  public
    constructor create(inifile:TConfigFile);
    destructor destroy; override;
  private
    CheckTimer:TTimer;
    SiteNotFoundCtr:integer;
    myversion:TVersion;
    lastfoundVersionapp,lastfoundVersiondrv:TVersion;
    inifile:TConfigFile;
    procedure CheckTimerEvent(Sender:TObject);
  end;

implementation

function EquVersion(l,r:TVersion):boolean;
begin
  result := false;
  if l = nil then exit;
  if r = nil then exit;
  if l.major=r.major then
    if l.minor = r.minor then
      if l.release = r.release then
        if l.build = r.build then
          if l.rev = r.rev then
            result := true;
end;

function cmpVersion(higher,smaller:TVersion):boolean;
begin
  result := false;
  if higher = nil then exit;
  if smaller = nil then exit;
  if higher.major=smaller.major then begin
    if higher.minor = smaller.minor then begin
      if higher.release = smaller.release then begin
        if higher.build = smaller.build then begin
          if higher.rev = smaller.rev then begin
            result := false;
          end else
            result := higher.rev>smaller.rev;
        end else
          result := higher.build > smaller.build;
      end else
        result := higher.release>smaller.release;
    end else
      result := higher.minor>smaller.minor;
  end else
    result := higher.major>smaller.major;
end;

{ TversionChecker }

constructor TversionChecker.create(inifile:TConfigFile);
var
  myver,myrev,mystate:string;
begin
  inherited create;
  CheckTimer:=TTimer.create(nil);
 // CheckTimer.Interval := 5*60*1000;
  SiteNotFoundCtr := 0;
  CheckTimer.Interval := 10000;
  CheckTimer.Enabled := true;
  CheckTimer.OnTimer := CheckTimerEvent;
  GetMyAppVersionValues(myver,myrev,mystate);
  myversion := TVersion.create(myver,myrev,mystate);
  self.inifile := inifile;
end;

destructor TversionChecker.destroy;
begin
  Checktimer.free;
  inherited;
end;

procedure TversionChecker.CheckTimerEvent(Sender: TObject);
var
  IdHttp: TIdHTTP;
  response: string;
  phpvars: string;
  s: string;
  //found: Boolean;
  xmlp: TXMLTagParser;
  tag: TXMLTag;
  t1: TXMLTag;
  t2: TXMLTag;
  t3: TXMLTag;
  versionlvl: TVersionCheckerLevel;
  //driverInfo: TDriverInfo;
  diverversion: TVersion;
  onlineversion: TVersion;
  buttonlist: TStringList;
  upavail: Boolean;
begin
  IdHttp := TIdHTTP.Create(nil);
  try
    upavail := false;
    (sender as TTimer).Enabled := false;
    (sender as TTimer).Interval := 5*60*1000;  //5 minuten
    xmlp := TXMLTagParser.Create;
    versionlvl := inifile.GetVersionCheckerLevel;
    {
    driverInfo := VibHardWareDriver.GetInfo;
    diverversion := TVersion.create(driverInfo.DriverVersion,'','');
    }
    try
      phpvars := '?lvl='+inttostr(VersionLevelToInt(versionlvl))+
                '&appmaj='+inttostr(myversion.major)+
                '&appmin='+inttostr(myversion.minor)+
                '&apprel='+inttostr(myversion.release)+
                '&appbuild='+inttostr(myversion.build)+
                '&apprev='+inttostr(myversion.rev)+
                '&appstate='+myversion.state;
                // Prof1983
                //'&drvname='+driverInfo.DriverName+
                //'&drvmaj='+inttostr(diverversion.major)+
                //'&drvmin='+inttostr(diverversion.minor);
      //if phpvars=''  then begin end;
      response := IdHttp.Get('http://traviesadora.sourceforge.net/versioncheck.php'+phpvars);

      SiteNotFoundCtr := 0;
    except
      on EIdHTTPProtocolException do
      begin
        inc(SiteNotFoundCtr);
        if SiteNotFoundCtr > 10 then
          (sender as TTimer).Enabled := false;
      end;
    end;
    xmlp.ParseString(response,'');
    tag := xmlp.popTag;
    if Assigned(tag) then
    begin
      onlineversion := nil;
      t1 := tag.GetFirstTag('application');
      if Assigned(t1) then
      begin
        if (versionlvl = vlAllUpdates) then
        begin
          t2 := t1.GetFirstTag('latest_version');
          s :='';
        end
        else
        begin
          t2 := t1.GetFirstTag('latest_important_version');
          s := 'important ';
        end;

        if Assigned(t2) then
        begin
          OnlineVersion := TVersion.CreateByTag(t2);
          if not EquVersion(onlineversion,lastfoundVersionapp) then
          begin
            if Assigned(LastFoundVersionApp) then
              FreeAndNil(LastFoundVersionApp);
            LastFoundVersionApp := TVersion.CreateByVersion(OnlineVersion);
            if cmpVersion(onlineversion,myversion) then
            begin
              upavail := true;
              buttonlist := TStringList.Create;
              try
                buttonlist.add('Download');
                buttonlist.add('Cancel');
                if FrmDialog.ShowModalA('Update available','There is a new '+s+'update available. ('+t2.GetBasicText('date')+')'+
                                      #13+t2.GetBasicText('desc'),ButtonList)=1  then
                begin
                  s := t2.GetBasicText('link_zip');
                  if s = '' then
                    s := t2.GetBasicText('link_setup');
                  if s = '' then
                    s := t2.GetBasicText('link');
                  shellexecute(0,'open',PCHAR(s),'','',SW_SHOW);

                end;
              finally
                buttonlist.Free;
              end;
            end;

          end;
          FreeAndNil(onlineversion);
        end;
      end;

      t1 := tag.GetFirstTag('drivers');
      if Assigned(t1) then
      begin
        t2 := t1.GetFirstTag('driver');
        if Assigned(t2) then
        begin
          if Versionlvl = vlAllUpdates then
          begin
            t3 := t2.GetFirstTag('latest_version');
            s :='';
          end
          else
          begin
            t3 := t2.GetFirstTag('latest_important_version');
            s := 'important ';
          end;

          if Assigned(t3) and (not upavail) then
          begin
            onlineversion := TVersion.CreateByTag(t3);
            if not EquVersion(onlineversion,lastfoundVersiondrv) then
            begin
              if Assigned(LastFoundVersionDrv) then
                freeandnil(LastFoundVersiondrv);
              lastfoundVersiondrv := TVersion.CreateByVersion(onlineversion);
              if cmpVersion(onlineversion, myversion) then
              begin
                ButtonList := TStringList.Create;
                try
                  ButtonList.Add('Download');
                  ButtonList.Add('Cancel');
                  if FrmDialog.ShowModalA('Update available','There is a new '+s+'update for the driver available. ('+t3.GetBasicText('date')+')'+
                                        #13+t2.GetBasicText('desc'),ButtonList)=1  then
                  begin
                    s := t3.GetBasicText('link_zip');
                    if s = '' then
                      s := t3.GetBasicText('link_setup');
                    if s = '' then
                      s := t3.GetBasicText('link');
                    ShellExecute(0,'open',PCHAR(s),'','',SW_SHOW);
                  end;
                finally
                  buttonlist.Free;
                end;
              end;

            end;
            FreeAndNil(onlineversion);
          end;
        end;
      end;
    end;
    (sender as TTimer).Enabled := true;
  finally
    IdHttp.Free;
    diverversion.free;
    xmlp.Free;
  end;
end;

{ TVersion }

constructor TVersion.create(ver:string;rev,state:string);
var
  a:string;
  b:string;
begin
  inherited create;
  major   :=0;
  minor   :=0;
  release :=0;
  build   :=0;
  self.rev := StrToIntDef(rev,0);
  self.state := state;

  a := ver;
  b := ver;
  delete(a,pos('.',a),length(a));
  delete(b,1,pos('.',b));
  major := StrToIntDef(a,0);
  a := b;
  delete(a,pos('.',a),length(a));
  if pos('.',b)=0 then b := '';
  delete(b,1,pos('.',b));
  minor := StrToIntDef(a,0);
  a := b;
  delete(a,pos('.',a),length(a));
  if pos('.',b)=0 then b := '';
  delete(b,1,pos('.',b));
  release := StrToIntDef(a,0);
  a := b;
  delete(a,pos('.',a),length(a));
  build := StrToIntDef(a,0);

end;

constructor TVersion.CreateByTag(xmltag: TXMLTag);
begin
  inherited create;
  major   :=StrToIntdef(xmltag.GetAttribute('major'),0);
  minor   :=StrToIntdef(xmltag.GetAttribute('minor'),0);
  release :=StrToIntdef(xmltag.GetAttribute('release'),0);
  build   :=StrToIntdef(xmltag.GetAttribute('build'),0);
  self.rev := StrToIntdef(xmltag.GetAttribute('rev'),0);
  self.state := xmltag.GetAttribute('status');
end;

constructor TVersion.CreateByVersion(v: TVersion);
begin
  inherited create;
  major   :=v.major;
  minor   :=v.minor;
  release :=v.release;
  build   :=v.build;
  self.rev := v.rev;
  self.state := v.state;
end;

end.
